Dynomotion

Group: DynoMotion Message: 9540 From: dbt3000files Date: 5/26/2014
Subject: restarting g code with c code
Can anyone help me with how to restart a g code program with a macro?  With our old machine, which ran on mach3, I was able to call g and m codes within a macro, so all I had to do was call an m99 after the macro had completed and I could restart the entire program.
Is there a way to do this with kmotion?  I have a c code that checks the condition of a vacuum.  Currently it disables the xy and z axis if the vacuum is unacceptable and it works fine, but what I would like it to do is to restart my routine.

Thanks,
David


Group: DynoMotion Message: 9541 From: Tom Kerekes Date: 5/26/2014
Subject: Re: restarting g code with c code
Hi David,

It isn't clear to me what you need or are trying to do. To arbitrarily rewind the GCode back to line 1 whenever the vacuum is unacceptable seem a bit dangerous.

There is a KFLOP to PC command that can Restart (Rewind) the GCode file to the beginning.  It is:

            DoPC(PC_COMM_RESTART);

But I did find that to be a bit of a catch22 because the Restart is not allowed by KMotionCNC while the GCode is running.  So it is required to Halt first and then Rewind.  But that results in a race condition unless we wait for the Halt to make the Job to go Inactive.  But then the Job never goes inactive because the M Code hasn't finished...  

The only solution that I found that worked reliably was to have the MCode perform a Halt and terminate, Configure the MCode to wait for it to finish (Exec/Wait/Sync), have the MCode set a virtual Bit as a flag to tell the Main Looping Thread to issue a delayed Restart as soon as the Job becomes inactive. 

So in the MCode add:

#include "KMotionDef.h"
#define TMP 10
#include "KflopToKMotionCNCFunctions.c"

main()
{
    DoPC(PC_COMM_HALT);
    SetBit(48);  //  flag to cause delayed restart

}


Then in the main loop add:

        if (ReadBit(48) && !JOB_ACTIVE)
        {
            ClearBit(48);
            DoPC(PC_COMM_RESTART);
        }



HTH
Regards
TK

Group: DynoMotion Message: 9543 From: dbt3000files Date: 5/26/2014
Subject: Re: restarting g code with c code
Thanks!  I think that will help.  You may have some advice about a better way to go about what I am doing, so if you'll bear with me, I'll give you a more detailed description about the routine.
This machine has a pick and place system, and a vacuum table.  It is picking up pieces of bamboo, and placing them on the vacuum table.  These pieces have lots of deviation, and occasionally they just won't form a good seal.  When this happens, the piece needs to be removed with the pick and place, and the program needs to be started over at the beginning of the g code subroutine.
Previously, on a machine using mach3, I was able to program a macro to check the vacuum condition, and, if it was not acceptable, remove the cane.  To accomplish this I used code" " function to run a g code routine to remove the cane.  At the end, all I had to do was include code " M99 " and it would restart to the beginning of the main subroutine.
Hope that makes sense.  I am open to any method that will accomplish this task, so if you or anyone else has any advice, I would really appreciate it. 
Thanks,
David
Group: DynoMotion Message: 9544 From: Tom Kerekes Date: 5/26/2014
Subject: Re: restarting g code with c code
Hi David,

It isn't clear to me how an Mach3 M99 would "restart to the beginning of the main subroutine".  I would think that would exit the current routine.  But I suppose is the main subroutine was to be looped many times then it would immediately re-call the subroutine?

If that is correct one possibility (which is a bit clumsy but might work) would be a structure like the psuedo code shown below.   It makes use of the "conditional subroutine calling" capability of KMotionCNC - and is structured programming :)

See the SubroutineWithConditionals.ngc example.

The LoadOneBamboo could set an Interpreter Variable like #100 based on vacuum present (Successful) or not.

Call DoOneBamboo many times
Stop


DoOneBambo:
   Call LoadOneBamboo 
   If Successful Call ProcessBamboo
   If Unsuccessful Call RemoveTheCane
   Return


HTH
Regards
TK


Group: DynoMotion Message: 9587 From: davidthreatte Date: 5/30/2014
Subject: Re: restarting g code with c code
Hi Tom,
I was able to write a script that either ejected and reloaded another piece of bamboo.  I didn't use the conditionals in the G code like you suggested, but instead used the Move and MoveAtVel functions to replicate the original G code that grabbed the cane.  I am using a K2cnc controller and machine.  Everything seemed to work fine, and I ran the machine for a while in this way, and then had the machine sitting idle for a while in disabled mode.  When started the routine again later, my rotary axes (A+B) started behaving erratically.  They would move at extremely high speeds to random locations without changing the numbers on the display, and with no error.  The same thing would happen when I tried to jog the rotary axes.  This problem may have nothing to do with the script, but it is the only thing new about the routine.
Do you have any ideas about what may be happening?  I am still waiting to hear back from K2, but I will take any advice I can get.  Obviously I  need to make sure I know exactly what went wrong before I start things up again. 

Thanks for all your help so far!
David
Group: DynoMotion Message: 9588 From: Tom Kerekes Date: 5/30/2014
Subject: Re: restarting g code with c code
Hi David,

I have no idea what that may be.  Post your code and we will look it over.  Also describe your system.  Is it open loop?  Closed Loop?  You also might run KMotion.exe to see what the axis Position, Destination, Enables, and such are doing while it is acting crazy.

Regards
TK


Group: DynoMotion Message: 9589 From: davidthreatte Date: 5/30/2014
Subject: Re: restarting g code with c code
The code is pretty long, so I posted it as an attachment.
It works with a programmable logic controller, so it has long sections marked click and unclick.  These are just pulses being sent to communicate with the controller so I can have many outputs and inputs using only the 2 outputs and inputs provided with the K2cnc controller.  These sections,such as the ones called check_2() or pick_and_place_cylinder(), are normally macros that are called independently, and have been working fine by themselves.  I am brand new to any sort of programming aside from G code, so some of it might be in pretty bad style.
I checked the Destination, Position, and Enable, and everything moved normally, and matched up until I tripped the b axis home switch, at which point the b axis twitched back and forth a few times, and the Destination and Position of the A axis changed to zero.

Thanks for looking at this for me,
David
  @@attachment@@
Group: DynoMotion Message: 9590 From: Tom Kerekes Date: 5/30/2014
Subject: Re: restarting g code with c code [1 Attachment]
Hi David,

I found that there were calls to a function called exit() that shouldn't be used.  That is intended for when the entire C system (KFLOP) shuts down.  Which should never occur.  I replaced those with:

        ThreadDone();         // call to terminate current thread               

That should do what I believe you intended to just stop one User thread.  I doubt if that was your problem but it is hard to say.

I also reformatted the indentation to what is the standard way most C programmers use where each nested block is indented one tab.  That makes it much more readable for most C Programmers but has no effect on the execution.

I also removed some duplicated defines and some unused variables.

Your coding style looks good to me.

I have no idea why tripping a home switch would cause anything to happen if a home sequence was not in progress.  Maybe there was a home sequence that was "stuck" and never completed?  

Regards
TK

Group: DynoMotion Message: 9591 From: dbt3000files Date: 5/30/2014
Subject: Re: restarting g code with c code [1 Attachment]
Thanks for looking at that code for me!  I was worried about those exit commands.  I think we figured out that there was a loose connection with one of the encoder wires, and it was causing the erratic movement.  My worry now is that if a connection were to get lose while the machine is running, it could destroy itself.  The machine only does one routine, so I can tweak the following error to be as low as possible, and hopefully catch abnormalities, but the motion I was witnessing would have probably not been stopped in time.  Do you have any suggestions for sensing something like this? 
Group: DynoMotion Message: 9592 From: Tom Kerekes Date: 5/30/2014
Subject: Re: restarting g code with c code
Hi David,

What type of system do you have?  Is it closed loop Steppers?  Servos?  What are your settings?

Ironically loss of encoder feedback while in motion will usually cause an immediate following error, but when stationary may not.  The servo may see a relatively small error and command the motor to correct it causing the motor to run away.  But because the encoder is broken the error never changes (appears to remain small) and so no following error occurs.  From the Servo's viewpoint it is trying harder and harder to correct what it thinks is this tiny error, all the while unbeknownst to it the motor is racing toward the end stop.  I'm not aware of a simple way to detect this scenario.  Normal cases may legitimately require large forces to correct small errors (ie cutting).  

Regards
TK


On Fri, May 30, 2014 at 5:01 PM, dbt3000files@... [DynoMotion] <DynoMotion@yahoogroups.com> wrote:
 

Thanks for looking at that code for me!  I was worried about those exit commands.  I think we figured out that there was a loose connection with one of the encoder wires, and it was causing the erratic movement.  My worry now is that if a connection were to get lose while the machine is running, it could destroy itself.  The machine only does one routine, so I can tweak the following error to be as low as possible, and hopefully catch abnormalities, but the motion I was witnessing would have probably not been stopped in time.  Do you have any suggestions for sensing something like this? 


Group: DynoMotion Message: 9596 From: davidthreatte Date: 5/31/2014
Subject: Re: restarting g code with c code
Sorry, I forgot to answer that the first time.  We are using a servo setup with encoders.  What you described is exactly what happened to our machine.  There was a loose connection that developed while the machine was stopped, and when it was started up again, the axis in question just started running away.  I guess the reason this hasn't been been a problem with industrial scale machines is that they have linear encoders that can be continually checked against the rotary.
I had an idea that might work for single task automation machines like ours.  If you only gave the machine a certain amount of time to resolve back to its prescribed position when in a stationary condition, that would at least minimize the amount that it could run away.  I was hoping the following code would work, but it doesn't recognize the Dest command. I also get a different number for the Pos command than I get when I run it on the console.  Any suggestions?

#include "KMotionDef.h"                       

main()
{
 float max_time_x = .01;                            //set your max time to allow x axis to resolve to position

 float test_dist = 80;                                             //set your test distance           

 float inv_test_dist = (test_dist * -1);                              //inverse of test distance

 while(1)                                                            //continually run the following check
 {
  if (CheckDone(0) == 1)                                                            //if x axis is not currently in a move         
  {
   if(((Dest(0) - Pos(0)) > test_dist) || ((Dest(0) - Pos(0)) < inv_test_dist))    //if difference between destination
   {                                                                                       //and position is greater than test distance
   
Delay_sec(max_time_x);                                                    //wait for the time allotted
 
    if(((Dest(0) - Pos(0)) > test_dist) || ((Dest(0) - Pos(0)) < inv_test_dist))     //if difference still greater than
                                                                                                            //test difference
               
    {
     Disable(0);                                                      //disable the x axis
   
     Printf("x axis did not resolve in time. You may have a loose connection\n");
    }
   }
  }         
 }
}
Group: DynoMotion Message: 9599 From: Tom Kerekes Date: 6/1/2014
Subject: Re: restarting g code with c code
Hi David,

The Desitnation for Axis Channel 0 can be referenced as ch0->Dest.  The measured Encoder Position for Axis Channel 0 can be referenced as ch0->Position.

Your program may work, it is certainly worth a try, but if there ever exists a condition where two errors greater than 80 counts happen to exist 10 milliseconds apart when stopping then your program might incorrectly disable the axis.   I would assume you feel it is normal to have errors greater than 80counts, otherwise you could just set the Max following error to 80 counts and fault.    Also it isn't clear than an error less that 80 counts wouldn't cause a motor run-away.

Regards
TK

Group: DynoMotion Message: 9610 From: dbt3000files Date: 6/3/2014
Subject: Re: restarting g code with c code
Thanks for the corrections.  My program worked well enough to illustrate nicely why it would be completely ineffective. :) 
I have a few more questions about this subject, but this thread has completely changed topics, so I should probably start a new one.